package org.itydl.game.model

import org.itheima.kotlin.game.core.Painter
import org.itydl.game.Config
import org.itydl.game.business.*
import org.itydl.game.enums.Direction

/**
 * 坦克
 */
// 接口x，y为val修饰，实现类可以是var类型。因为坦克是移动物体，坐标是变量，定义为 var
class Tank(override var x: Int, override var y: Int) :
        Movable, Blockable, Sufferable, Destoryable { // 移动(检测碰撞)、阻挡能力、遭受击打能力、销毁能力

    /**
     * 宽高,跟墙大小一样
     */
    override val width: Int = Config.block
    override val height: Int = Config.block

    /**
     * 当前坦克的方向，默认为 UP
     */
    override var currentDirection = Direction.UP

    /**
     * 坦克移动的速度，每次移动 8 长度的距离
     */
    override val speed: Int = 8

    private var currentBadDirection: Direction? = null

    /**
     * 我方坦克的血量
     */
    override var blood: Int = 20

    /**
     * @direction 移动的下一个方向
     */
    fun move(direction: Direction) {

        // 碰撞方向不可再移动
        // 下一个方向是碰撞方向
        if (currentBadDirection == direction) {
            return
        }

        if (currentDirection != direction) {
            // 想要移动的方向跟当前方向不一致时，只是改变方向，不移动坦克
            currentDirection = direction
            return
        }

        // 移动坦克
        when (currentDirection) {
            Direction.UP -> y -= speed
            Direction.DOWN -> y += speed
            Direction.LEFT -> x -= speed
            Direction.RIGHT -> x += speed
        }

        // 处理越界--画图理解
        if (x < 0) x = 0
        if (x > Config.gameWidth - width) x = Config.gameWidth - width
        if (y < 0) y = 0
        if (y > Config.gameHeight - height) y = Config.gameHeight - height
    }

    /**
     * 根据【方向】绘制坦克
     */
    override fun draw() {
        val tankImagePath = when (currentDirection) {
            Direction.UP -> "img/tank_u.gif"
            Direction.DOWN -> "img/tank_d.gif"
            Direction.LEFT -> "img/tank_l.gif"
            Direction.RIGHT -> "img/tank_r.gif"
        }
        Painter.drawImage(tankImagePath, x, y)
    }

    override fun notifyCollication(direction: Direction?, blockable: Blockable?) {
        // 收到碰撞通知，记录给当前移动物体。记录方向（碰撞方向不能再移动）
        currentBadDirection = direction
    }

    /**
     * 子弹具备发射子弹(其实就是根据坦克的当前位置，创造子弹对象赋予其正确的位置)的行为
     */
    fun shot(): Bullet {
        // 根据坦克的位置计算子弹的坐标（跟坦克的方向有关）

        // 根据坦克的位置、方向，计算坦克发射的位置
        // 传入this，表示当前子弹是由我方子弹发射出去的
        return Bullet(this, currentDirection) { bulletWidth, bulletHeight ->
            // 闭包是最后一个参数，应该放在后面，该函数在Bullet中调用
            // 函数入参bulletWidth,bulletHeight，-> 最后一行为返回值
            val tankWidth: Int = width
            val tankHeight: Int = height

            val tankX: Int = x
            val tankY: Int = y

            var bulletX = 0
            var bulletY = 0
            when (currentDirection) {
                Direction.UP -> {
                    // bulletWidth和bulletHeight应该由子弹传递过来
                    bulletX = tankX + (tankWidth - bulletWidth) / 2
                    bulletY = tankY - bulletHeight / 2
                }

                Direction.DOWN -> {
                    bulletX = tankX + (tankWidth - bulletWidth) / 2
                    bulletY = tankY + tankHeight - bulletHeight / 2
                }

                Direction.LEFT -> {
                    bulletX = tankX - bulletWidth / 2
                    bulletY = tankY + (tankHeight - bulletHeight) / 2
                }

                Direction.RIGHT -> {
                    bulletX = tankX + tankWidth - bulletWidth / 2
                    bulletY = tankY + (tankHeight - bulletHeight) / 2
                }
            }
            // 闭包的返回值类型是 Pair
            Pair<Int, Int>(bulletX, bulletY)
        }
    }

    // 我方坦克遭受攻击
    override fun notifySuffered(attackable: Attackable): Array<View>? {
        // 遭受攻击血量递减,给个遭受攻击的反馈
        blood -= attackable.power
        return arrayOf(Blast(x, y))
    }

    override fun isDestory(): Boolean {
        return blood <= 0
    }
}